<html>
<head>

<title>Groovy Goodness: Refactor XML Creation with StreamingMarkupBuilder</title>

<script language="javascript" src="scripts/shCore.js"></script> 
<script language="javascript" src="scripts/shLegacy.js"></script> 
<script language="javascript" src="scripts/shBrushJava.js"></script> 
<script language="javascript" src="scripts/shBrushXml.js"></script> 
<script language="javascript" src="scripts/shBrushJScript.js"></script> 
<script language="javascript" src="scripts/shBrushGroovy.js"></script> 
<script language="javascript" src="scripts/shBrushPlain.js"></script> 
<script language="javascript" src="scripts/shBrushBash.js"></script> 
 
<link href="styles/reset.css" rel="stylesheet" type="text/css" />
<link href="styles/shCore.css" rel="stylesheet" type="text/css" />
<link type="text/css" rel="stylesheet" href="styles/shThemeRDark.css"/>
<link href="styles/blog.css" rel="stylesheet" type="text/css" />

</head>
<body>

<a href="index.html">Back to index</a>

<h3 class="post-title">Groovy Goodness: Refactor XML Creation with StreamingMarkupBuilder</h3>

<div class="post">
<p>On Groovy's website we can find the article <a href="http://groovy.codehaus.org/Using+MarkupBuilder+for+Agile+XML+creation">Using MarkupBuilder for Agile XML creation</a>. Here we read how we create parts of the XML in separate methods, so we don't have to repeat ourselves if we are building XML. In this blog post we see a small example applying the same principles, but now we use <code>StreamingMarkupBuilder</code>. For the <code>StreamingMarkupBuilder</code> we must pass a closure to the <code>bind()</code> method. The closure contains a reference to the builder and we can use it in methods to define parts of the XML.</p>
<pre class="brush:groovy">
import groovy.xml.*

def markupBuilder = new StreamingMarkupBuilder()
def xml = markupBuilder.bind { builder -&gt;
 client {
  name 'mrhaki'
  fullName 'Hubert A. Klein Ikkink'
  buildAddress builder, 'Main St.', 42, 'Ducktown'
  delivery {
      buildAddress builder, 'Main Av.', 101, 'Springfield'
      remarks 'During office hours'
  }
  buildItems builder
 }
}

def buildAddress(builder, streetName, number, city) {
 builder.address {
  street streetName
  houseNumber number
  buildCity builder, city
 }
}

def buildCity(builder, city) {
 builder.city city
}

def buildItems(builder) {
    builder.items {
     ['iPod', 'eBook'].eachWithIndex { product, index -&gt;
      item(id: index + 1) {
       name "Item $product"
      }
     }
    }
}

assert '''&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;client&gt;
  &lt;name&gt;mrhaki&lt;/name&gt;
  &lt;fullName&gt;Hubert A. Klein Ikkink&lt;/fullName&gt;
  &lt;address&gt;
    &lt;street&gt;Main St.&lt;/street&gt;
    &lt;houseNumber&gt;42&lt;/houseNumber&gt;
    &lt;city&gt;Ducktown&lt;/city&gt;
  &lt;/address&gt;
  &lt;delivery&gt;
    &lt;address&gt;
      &lt;street&gt;Main Av.&lt;/street&gt;
      &lt;houseNumber&gt;101&lt;/houseNumber&gt;
      &lt;city&gt;Springfield&lt;/city&gt;
    &lt;/address&gt;
    &lt;remarks&gt;During office hours&lt;/remarks&gt;
  &lt;/delivery&gt;
  &lt;items&gt;
    &lt;item id="1"&gt;
      &lt;name&gt;Item iPod&lt;/name&gt;
    &lt;/item&gt;
    &lt;item id="2"&gt;
      &lt;name&gt;Item eBook&lt;/name&gt;
    &lt;/item&gt;
  &lt;/items&gt;
&lt;/client&gt;
''' == XmlUtil.serialize(xml)
</pre
</div>

<script language="javascript"> 
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'scripts/clipboard.swf';
SyntaxHighlighter.defaults['first-line'] = 0;
SyntaxHighlighter.defaults['auto-links'] = false;
SyntaxHighlighter.all();
dp.SyntaxHighlighter.HighlightAll('code');
</script>

</body>
</html>